#include "port.h"

// One time include to game.cpp
// To reduce the line size (and improve readability) of it
// Begin cross platform TIMER code
#if defined(unix) || defined(__unix__) || defined(__unix)
	#include <unistd.h>
#endif

#if defined(_WIN32)
	LARGE_INTEGER curTime;
	LARGE_INTEGER prevTime;
	LARGE_INTEGER ticksPs;
	
	void timer_init() {}
	
	void setTimer() {
		QueryPerformanceFrequency(&ticksPs);
		QueryPerformanceCounter(&prevTime);
	}
	
	double getDelta() {
		double delta;
		QueryPerformanceCounter(&curTime);
		delta = double(curTime.QuadPart-prevTime.QuadPart)/double(ticksPs.QuadPart);
		memcpy(&prevTime, &curTime, sizeof(LARGE_INTEGER));
		
		return delta;
	}
#elif (_POSIX_VERSION) >= 200112L // Which supports gettimeofday()
	#include <sys/time.h>
	
	struct timeval curTime;
	struct timeval prevTime;
	double __timer_delta;
	double __frame_time;
	
	void timer_init() {}
	
	void setTimer() {
		gettimeofday(&prevTime, NULL);
	}

	bool newFrame() {
		gettimeofday(&curTime, NULL);
		if(curTime.tv_usec > prevTime.tv_usec) {
			__timer_delta = double(curTime.tv_usec-prevTime.tv_usec)/double(1.0e6); // Microsec timer
		}else {
			__timer_delta = double((1.0e6+curTime.tv_usec)-prevTime.tv_usec)/double(1.0e6); // Microsec timer
		}
		
		// Have to let old frames 'leak over' if they were too long
		if(__timer_delta+(__frame_time-1.0/double(FPS)) > 1.0/double(FPS)) return true;
		else return false;
	}
	
	double getDelta() {
		__frame_time = __timer_delta;
		newFrame();
		prevTime.tv_usec = curTime.tv_usec;
		
		return __timer_delta;
	}
	
#else
	volatile int timer = 0;
	void set_timer(void) { timer++; } END_OF_FUNCTION(set_timer);
	
	void timer_init() {
	    LOCK_VARIABLE(timer);
	    LOCK_FUNCTION(set_timer);
	    install_int_ex(set_timer, BPS_TO_TIMER(FPS));
	}
	
	void setTimer() { timer = 0; }
	
	bool newFrame() { return (timer>0); }
	
	double getDelta() {
		double delta = double(timer)/double(FPS);
		timer = 0;
		return(delta);
	}
#endif


// End cross platform TIMER code

